package com.yang.auth.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.yang.auth.constant.RedisKeyConstant;
import com.yang.auth.enums.ResponseCodeEnum;
import com.yang.auth.model.vo.verificationcode.SendVerificationCodeReqVo;
import com.yang.auth.service.IVerificationCodeService;
import com.yang.auth.util.email.SendEmailUtil;
import com.yang.auth.util.sms.AliyunSmsHelper;
import com.yang.framework.common.exception.biz.BizException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class VerificationCodeServiceImpl implements IVerificationCodeService {

    @Resource(name = "taskExecutor")
    private ThreadPoolTaskExecutor executor;    //  线程池
    @Resource
    private AliyunSmsHelper aliyunSmsHelper;    //  发短信的工具类
    @Resource
    private RedisTemplate<String, Object> redisTemplate;    //  redis操作类
    @Resource
    private SendEmailUtil sendEmailUtil;    //  邮箱发送工具

    @Override
    public void send(SendVerificationCodeReqVo sendVerificationCodeReqVo) {

        //  1.生成验证码的key、value
        String verificationCodeKey = RedisKeyConstant.getVerificationCodeKey(sendVerificationCodeReqVo.getPhone());
        String verificationCodeValue = RandomUtil.randomNumbers(6);

        //  2.用lua脚本判断这个手机号3分钟内是否发送过短信，如果发送过，则不让发送
        String luaScript = """
                if (redis.call('exists', KEYS[1])==1) then
                    return false
                else
                    redis.call('set', KEYS[1], ARGV[1], 'ex', 180)
                    return true
                end
                """;
        Boolean storeResult = redisTemplate.execute(new DefaultRedisScript<>(luaScript,Boolean.class), List.of(verificationCodeKey), verificationCodeValue);
        //  3.三分钟内重复发送验证码
        if (!Boolean.TRUE.equals(storeResult)) {
            throw new BizException(ResponseCodeEnum.VERIFICATION_CODE_SEND_FREQUENTLY);
        }

        //  4.调用第三方服务，向用户发送短信（异步发送短信）
        executor.submit(() -> {
//            aliyunSmsHelper.sendMessage(sendVerificationCodeReqVo.getPhone(), verificationCodeValue);
            //  用QQ邮箱代替短信
            String sender = "3079314177@qq.com";
            String receiver = "3079314177@qq.com";
            String email = "验证码：" + verificationCodeValue;
            sendEmailUtil.send(sender, receiver, email);
        });

        log.info("===> 手机号：{}，已发送验证码：{}",sendVerificationCodeReqVo.getPhone(), verificationCodeValue);
    }
}
